public class Leetcode {
}

//leetcode:152:乘积最大子数组
class Solution1 {
    public int maxProduct(int[] nums) {
        int n = nums.length;

        //设立两个数组f代表最大值，g代表最小值
        int[] f = new int[n+1];
        int[] g = new int[n+1];

        //因为是乘积为了防止干扰，我们将0位置的值初始化为1
        f[0] = 1;
        g[0] = 1;

        int ret = Integer.MIN_VALUE;
        for(int i = 1; i <= n; i++){
            //计算得出，是此时这个位置的值大还是，最大值乘于这个位置的值或最小值乘于这个位置的值大
            f[i] = Math.max(nums[i-1] , Math.max(f[i-1] * nums[i-1] , g[i-1] * nums[i-1]));
            //计算得到这个位置的最小值
            g[i] = Math.min(nums[i-1] , Math.min(f[i-1] * nums[i-1] , g[i-1] * nums[i-1]));
            ret = Math.max(ret, f[i]);
        }
        return ret;
    }
}

//leetcode:乘积为正数的最长子数组长度
class Solution2 {
    public int getMaxLen(int[] nums) {
        int n = nums.length;

        //设立两个数组f代表这个位置存入乘积为正数的长度，g代表这个为存入乘积为负数的长度
        int[] f = new int[n+1];
        int[] g = new int[n+1];

        //如果最后整个数组的子树乘积为负数，那么我们就返回0，所以我们将初始位置设为0
        f[0] = g[0] = 0;

        int ret = 0;
        for(int i = 1; i <= n; i++){
            //如果此时的值为正数
            if(nums[i-1] > 0){
                //此时乘积为正数的子序列的长度就为前一个位置长度加一
                f[i] = f[i-1] + 1;
                //而乘积为负数的子序列长度，如果前一个位置长度为0，而此时的位置为正数，那么此时位置的g[i]就等于0，因为g是存入负数的长度，如果不为0，那么此时的长度就为前一个负数的长度加一,因为前一个的乘积为负数再乘于正数还为负数，所可以得到结果
                g[i] = g[i-1] == 0 ? 0 : g[i-1] + 1;
            }
            //如果此时的值为负数
            if(nums[i-1] < 0){
                //此时乘积为正数的子序列长度，就要判断前一个位置的g是否等于0，如果等于就代表前面没有乘积为负数的情况，而此时的负数无论怎么乘都将为负数，所以此时的f[1] == 0,如果前一个位置的g有值，那么此时位置的长度就为前一个负数的长度加一，因为前一个的乘积为负数再乘于负数数就为为正数，所可以得到结果
                f[i] = g[i-1] == 0 ? 0 : g[i-1] + 1;
                //而乘积为负数的子序列长度为，前一个位置为正数的长度加一
                g[i] = f[i-1] + 1;
            }
            ret = Math.max(ret,f[i]);
        }
        return ret;
    }
}